package com.project.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.project.entity.Custom;
import com.project.service.CustomService;
import com.project.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.BindingResult;

import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController

@Api(tags = "客户管理")
@RequestMapping("/custom")
public class CustomController {

    @Autowired
    public CustomService service;

    @Autowired
    RedisTemplate<String,Object> redisTemplate;
   @Autowired
  public RLock rLock;


    @ApiOperation(value = "查询")
    @GetMapping("cutByItem")
    public IPage<Custom> cutByItem(Integer pageNo, String name, String scope) {
        return service.cutByItem(pageNo, name, scope);
    }

    @ApiOperation(value = "添加客户")
    @PostMapping("addCustom")
    public String addCustom(@Valid Custom custom, BindingResult result) throws JsonProcessingException {
        //判断是否有校验失败的错误信息
        if (result.hasFieldErrors()) {
            //得到校验失败的集合
            List<FieldError> errorList = result.getFieldErrors();
            //将错误信息转化为json字符串
            ObjectMapper om = new ObjectMapper();
            String errorJson = om.writeValueAsString(errorList);
            return errorJson;
        }
        service.addCustom(custom);
        return "ok";
    }

    @ApiOperation(value = "查看客户信息")
    @GetMapping("findById/{id}")
    public Custom findById(@PathVariable("id") Integer id) throws InterruptedException {
      String key = String.valueOf(id);
      Custom custom = null;
      if (redisTemplate.hasKey(key)){
          //存在缓存
          Object o =  redisTemplate.opsForValue().get(key);
          //   将Object转化为某一个实体类对象
          String jsonString = JSONObject.toJSONString(o);
          custom = JSONObject.parseObject(jsonString,Custom.class);
      }else {
          //竞争锁
          boolean bl = rLock.tryLock(0,10,TimeUnit.SECONDS);
          //如果拿到锁
          if (bl){
              //不存在缓存
              custom = service.findById(id);
              //防止缓存雪崩
            long keyNum = key.hashCode();
            //随机获取值,0-最大值之间
            int number = (int) (keyNum % StringUtil.CACHE_TIME_MAX);
            //随机值小于最小缓存时间，就为最小缓存时间
            if (number < StringUtil.CACHE_TIME_MIN){
                number = StringUtil.CACHE_TIME_MIN;
            }
            //判断数据库是否有查询的数据
            if (custom == null){
                //数据库无数据，设置最小缓存时间
             redisTemplate.opsForValue().set(key,custom,StringUtil.CACHE_TIME_MIN,TimeUnit.SECONDS);
            }else {
                redisTemplate.opsForValue().set(key,custom,number,TimeUnit.SECONDS);
            }
            //释放锁
              rLock.unlock();
          }else {
              //没有拿到锁
              Thread.sleep(500);  //休眠等待500毫秒
              this.service.findById(id);  //重新竞争锁
          }
      }
        return custom;
    }

    @ApiOperation(value = "修改客户信息")
    @PutMapping("updateHeadAndPhone/{id}/{head}/{headPhone}")
    public String updateHeadAndPhone(Integer id, String head, String headPhone) {
        service.updateHeadAndPhone(id, head, headPhone);
        return "ok";
    }
}
